#! /bin/sh
#
# rc.6		This file is executed by init when it goes into runlevel
#		0 (halt) or runlevel 6 (reboot). It kills all processes,
#		unmounts file systems and then either halts or reboots.
#
# Version:	@(#)/etc/rc.d/rc.6	2.47 Sat Jan 13 13:37:26 PST 2001
#
# Author:	Miquel van Smoorenburg <miquels@drinkel.nl.mugnet.org>
# Modified by:  Patrick J. Volkerding, <volkerdi@slackware.com>
# Modified by:  Ole Andre Rodlie, <olear@slackforge.net>

# Set the path.
PATH=/sbin:/etc:/bin:/usr/bin

# Set linefeed mode to avoid staircase effect.
/bin/stty onlcr

echo "Running shutdown script $0:"

# Find out how we were called.
case "$0" in
	*0)
		command="halt"
		;;
	*6)
		command=reboot
		;;
	*)
		echo "$0: call me as \"rc.0\" or \"rc.6\" please!"
		exit 1
		;;
esac

# Save the system time to the hardware clock using hwclock --systohc.
if [ -x /sbin/hwclock ]; then
  # Check for a broken motherboard RTC clock (where ioports for rtc are
  # unknown) to prevent hwclock causing a hang:
  if ! grep -q -w rtc /proc/ioports ; then
    CLOCK_OPT="--directisa"
  fi
  if grep -q "^UTC" /etc/hardwareclock 2> /dev/null ; then
    echo "Saving system time to the hardware clock (UTC)."
    /sbin/hwclock $CLOCK_OPT --utc --systohc
  else
    echo "Saving system time to the hardware clock (localtime)."
    /sbin/hwclock  $CLOCK_OPT --localtime --systohc
  fi
fi

# Stop X
if [ -x /etc/rc.d/rc.x11 ]; then
  /bin/sh /etc/rc.d/rc.x11 stop
fi

# Stop DRACO
if [ -x /etc/rc.d/rc.draco ]; then
  /bin/sh /etc/rc.d/rc.draco stop
fi

# Run any local shutdown scripts:
if [ -x /etc/rc.d/rc.local_shutdown ]; then
  /bin/sh /etc/rc.d/rc.local_shutdown stop
fi

# Stop HALD
if [ -x /etc/rc.d/rc.hald ]; then
  /bin/sh /etc/rc.d/rc.hald stop
fi

# Stop DBUS
if [ -x /etc/rc.d/rc.messagebus ]; then
  /bin/sh /etc/rc.d/rc.messagebus stop
fi

# Stop OSS:
if [ -x /etc/rc.d/rc.oss ]; then
  /bin/sh /etc/rc.d/rc.oss stop
fi

# Stop SSH:
if [ -x /etc/rc.d/rc.sshd ]; then
  /bin/sh /etc/rc.d/rc.sshd stop
fi

# Stop dnsmasq
if [ -x /etc/rc.d/rc.dnsmasq ]; then
  /bin/sh /etc/rc.d/rc.dnsmasq stop
fi

# Stop ntpd
if [ -x /etc/rc.d/rc.ntpd ]; then
  /bin/sh /etc/rc.d/rc.ntpd stop
fi

# Stop inetd:
if [ -x /etc/rc.d/rc.inetd ]; then
  /bin/sh /etc/rc.d/rc.inetd stop
fi

# Unmount any NFS, SMB, or CIFS filesystems:
echo "Unmounting remote filesystems."
/bin/umount -v -a -r -t nfs,smbfs,cifs

# Try to shut down pppd:
PS="$(ps ax)"
if echo "$PS" | /bin/grep -q -w pppd ; then
  if [ -x /usr/sbin/ppp-off ]; then
    /usr/sbin/ppp-off
  fi
fi

# Bring down the networking system, but first make sure that this
# isn't a diskless client with the / partition mounted via NFS:
if ! /bin/mount | /bin/grep -q 'on / type nfs' ; then
  if [ -x /etc/rc.d/rc.inet1 ]; then
    /bin/sh /etc/rc.d/rc.inet1 stop
  fi
fi

# In case dhcpcd might have been manually started on the command line,
# look for the .pid file, and shut dhcpcd down if it's found:
if /bin/ls /etc/dhcpc/*.pid 1> /dev/null 2> /dev/null ; then
  /sbin/dhcpcd -k 1> /dev/null 2> /dev/null
  # A little time for /etc/resolv.conf and/or other files to
  # restore themselves.
  sleep 2
fi

# Shut down PCMCIA devices:
if [ -x /etc/rc.d/rc.pcmcia ]; then
  /bin/sh /etc/rc.d/rc.pcmcia stop
  # The cards might need a little extra time here to deactivate:
  /bin/sleep 5
fi

# Turn off process accounting:
if [ -x /sbin/accton -a -r /var/log/pacct ]; then
  echo "Turning off process accounting."
  /sbin/accton
fi

# Kill all processes.
# INIT is supposed to handle this entirely now, but this didn't always
# work correctly without this second pass at killing off the processes.
# Since INIT already notified the user that processes were being killed,
# we'll avoid echoing this info this time around.
if [ ! "$1" = "fast" ]; then # shutdown did not already kill all processes
  /sbin/killall5 -15 
  /bin/sleep 5
  /sbin/killall5 -9
fi

# Try to turn off quota.
if /bin/grep -q quota /etc/fstab ; then
  if [ -x /sbin/quotaoff ]; then
    echo "Turning off filesystem quotas."
    /sbin/quotaoff -a
  fi
fi

# Carry a random seed between reboots.
echo "Saving random seed from /dev/urandom in /etc/random-seed."
# Use the pool size from /proc, or 512 bytes:
if [ -r /proc/sys/kernel/random/poolsize ]; then
  /bin/dd if=/dev/urandom of=/etc/random-seed count=1 bs=$(cat /proc/sys/kernel/random/poolsize) 2> /dev/null
else
  /bin/dd if=/dev/urandom of=/etc/random-seed count=1 bs=512 2> /dev/null
fi
/bin/chmod 600 /etc/random-seed

# Before unmounting file systems write a reboot or halt record to wtmp.
$command -w

# Clear /var/lock/subsys.
if [ -d /var/lock/subsys ]; then
  rm -f /var/lock/subsys/*
fi

# Turn off swap:
echo "Turning off swap."
/sbin/swapoff -a
/bin/sync

# Umount any LVM volumes:
if /bin/mount | /bin/grep -q '^/dev/mapper/' ; then
  echo "Unmounting LVM volumes."
  /bin/umount -v $(/bin/mount | /bin/grep '^/dev/mapper/' | /bin/cut -d ' ' -f 3 | /bin/tac)
fi

echo "Unmounting local file systems."
/bin/umount -v -a -t no,proc,sysfs

echo "Remounting root filesystem read-only."
/bin/mount -v -n -o remount,ro /

# This never hurts:
/bin/sync

# Close any volumes opened by cryptsetup:
if [ -f /etc/crypttab -a -x /sbin/cryptsetup.static ]; then
  cat /etc/crypttab | grep -v "^#" | grep -v "^$" | while read line; do
    # NOTE: we only support LUKS formatted volumes (except for swap)!
    LUKS=$(echo $line | tr '\t' ' ' | tr -s ' ' | cut -f1 -d' ')
    DEV=$(echo $line | tr '\t' ' ' | tr -s ' ' | cut -f2 -d' ')
    OPTS=$(echo $line | tr '\t' ' ' | tr -s ' ' | cut -f4 -d' ')
    if /sbin/cryptsetup.static isLuks $DEV 2>/dev/null ; then
      echo "Locking LUKS crypt volume '${LUKS}':"
      /sbin/cryptsetup.static luksClose ${LUKS}
    elif echo $OPTS | grep -wq swap ; then
      # If any of the volumes was used as encrypted swap,
      # then run mkswap on the underlying device -
      # in case other Linux installations on this computer should use it:
      echo "Erasing encrypted swap '${LUKS}' and restoring normal swap on ${DEV}:"
      /sbin/cryptsetup.static remove ${LUKS}
      mkswap $DEV
    fi
  done
fi

# Deactivate LVM volume groups:
if [ -r /etc/lvmtab -o -d /etc/lvm/backup ]; then
  echo "Deactivating LVM volume groups:"
  /sbin/vgchange -an --ignorelockingfailure
fi

# This never hurts again (especially since root-on-LVM always fails
# to deactivate the / logical volume...  but at least it was
# remounted as read-only first)
/bin/sync

# sleep 3 fixes problems with some hard drives that don't
# otherwise finish syncing before reboot or poweroff
/bin/sleep 3

# This is to ensure all processes have completed on SMP machines:
wait

if [ -x /sbin/genpowerd ]; then
  # See if this is a powerfail situation:
  if /bin/egrep -q "FAIL|SCRAM" /etc/upsstatus 2> /dev/null ; then
    # Signal UPS to shut off the inverter:
    /sbin/genpowerd -k
    if [ ! $? = 0 ]; then
      echo
      echo "There was an error signaling the UPS."
      echo "Perhaps you need to edit /etc/genpowerd.conf to configure"
      echo "the serial line and UPS type."
      # Wasting 15 seconds of precious power:
      /bin/sleep 15
    fi
  fi
fi

# Now halt (poweroff with APM or ACPI enabled kernels) or reboot.
if [ "$command" = "reboot" ]; then
  echo "Rebooting."
  /sbin/reboot
else
  /sbin/poweroff
fi

